<template>
  <view v-if="windowInfo && proto">
    <canvas
      id="proto-poster-canvas"
      canvas-id="proto-poster-canvas"
      :style="{
        width: `${windowInfo.windowWidth}px`,
        height: `${windowInfo.windowHeight - (windowInfo.statusBarHeight + windowInfo.safeArea.top)}px`,
      }"
      class="proto-canvas"
    ></canvas>
  </view>
</template>

<script setup lang="ts">
import './index.less';
import { onMounted, PropType, ref } from 'vue';
import Taro from '@tarojs/taro';
import { ProtoType } from '@/api/proto';

const windowInfo = Taro.getWindowInfo();
const props = defineProps({
  proto: {
    type: Object as PropType<ProtoType>,
    default: null,
  },
  winHeight: Number,
  winWidth: Number,
  posterId: {
    type: String,
    default: 'poster-canvas-1',
  },
});

// canvas多文字换行
const wrapText = (text, width, context, rows = 2) => {
  const txtArr = text.split('');
  let temp = '';
  let row = [];
  for (let i = 0, len = txtArr.length; i < len; i++) {
    if (context.measureText(temp).width < width - 30) {
      temp += txtArr[i];
    } else {
      i--;
      row.push(temp);
      temp = '';
    }
  }
  row.push(temp);
  if (row.length > rows) {
    const rowCut = row.slice(0, rows);
    const rowPart = rowCut[rows - 1];
    let test = '';
    const empty = [];
    for (let j = 0, { length } = rowPart; j < length; j++) {
      if (context.measureText(test).width < width - 30) {
        test += rowPart[j];
      } else {
        break;
      }
    }
    empty.push(test);
    const group = `${empty[0]}...`;
    rowCut.splice(rows - 1, 1, group);
    row = rowCut;
  }
  return row;
};
const modal = (callback: (ok: boolean) => void) => {
  Taro.showModal({
    title: '提示',
    content: '您还没有开启相册权限，是否立即设置？',
    showCancel: true,
    cancelColor: '#555',
    confirmColor: '#EB0909',
    confirmText: '确定',
    success(res) {
      if (res.confirm) {
        callback(true);
      } else {
        callback(false);
      }
    },
  });
};
const judgePermissionPhotoLibrary = (callback: (status: boolean) => void) => {
  Taro.authorize({
    scope: 'scope.writePhotosAlbum',
    success() {
      callback(true);
    },
    fail() {
      modal((res) => {
        if (res) {
          Taro.openSetting({
            success(res) {
              console.log(res.authSetting);
            },
          });
        }
      });
    },
  });
};
const saveImage = (file) => {
  // 检查是否授权相册权限
  judgePermissionPhotoLibrary((res) => {
    // 保存图片
    if (res) {
      Taro.saveImageToPhotosAlbum({
        filePath: file,
        success(res) {
          Taro.showToast({
            title: '图片保存成功',
            icon: 'none',
          });
        },
        fail(res) {
          Taro.showToast({
            title: '图片保存失败',
            icon: 'none',
          });
        },
      });
    }
  });
};
// 生成海报图片(分享所需图片)
const createPoster = (canvasId, winWidth, winHeight, callback: (path: string) => void) => {
  Taro.canvasToTempFilePath(
    {
      x: 0,
      y: 0,
      width: winWidth,
      height: winHeight,
      canvasId,
      fileType: 'jpg',
      success(res) {
        callback(res.tempFilePath);
      },
      fail(err) {
        callback('');
      },
    },
    this,
  );
};
let context;
const canvasId = 'proto-poster-canvas';
const readyProtoPoster = (
  cover: string,
  qrcode: string,
  title: string,
  price: string,
  commission: string,
  commissionRate: string,
  desc: string,
  callback: (res: string) => void,
) => {
  const winHeight = windowInfo.windowHeight;
  // const winHeight = 680;
  const winWidth = windowInfo.windowWidth;
  // const winWidth = 380;
  // 获取绘图上下文 context
  context = Taro.createCanvasContext(canvasId);
  // 海报背景
  const grd = context.createLinearGradient(0, 400, 1200, 0);
  grd.addColorStop(0, '#fff');
  grd.addColorStop(1, '#fff');
  // Fill with gradient
  context.setFillStyle(grd);
  context.fillRect(0, 0, winWidth, winHeight);
  function upx2px(number: number) {
    return number;
  }
  // 主图
  const width = upx2px(winWidth);
  const height = upx2px(winWidth);
  context.drawImage(cover, (winWidth - width) / 2, upx2px(0), width, height);
  const a = upx2px(22); // 定义行高
  context.setFontSize(upx2px(18));
  context.setFillStyle('#202020');
  const w = upx2px(winWidth);
  // 名称很长调用方法将文字折行，传参 文字内容text，画布context
  const row = wrapText(title, Math.floor(w), context, 2);
  let nextLineX = Number(height) + 40;
  for (let i = 0; i < row.length; i++) {
    context.fillText(row[i], upx2px(10), upx2px(nextLineX) + a * i);
  }
  nextLineX += 46;
  context.setFillStyle('#303030');
  context.setFontSize(upx2px(16));
  context.fillText('成交价 ', upx2px(12), upx2px(nextLineX));
  context.setFillStyle('#303030');
  context.setFontSize(upx2px(10));
  context.fillText('￥', upx2px(60), upx2px(nextLineX));
  context.setFillStyle('#303030');
  context.setFontSize(upx2px(16));
  context.fillText(price, upx2px(70), upx2px(nextLineX));
  nextLineX += 20;
  context.setFillStyle('#303030');
  context.setFontSize(upx2px(16));
  context.fillText('佣金比 ', upx2px(12), upx2px(nextLineX));
  context.setFillStyle('#303030');
  context.setFontSize(upx2px(16));
  context.fillText(commissionRate, upx2px(70), upx2px(nextLineX));
  context.setStrokeStyle('#999999');
  context.stroke(); // 对当前路径进行描边
  // 识别小程序二维码
  context.drawImage(qrcode, winWidth - (width / 4 + 22), upx2px(height + 60), upx2px(width / 4), upx2px(height / 4));
  nextLineX += 30;
  context.setFillStyle('#fa020a');
  context.setFontSize(upx2px(22));
  context.fillText('赚', upx2px(12), upx2px(nextLineX));
  context.setFillStyle('#fa020a');
  context.setFontSize(upx2px(12));
  context.fillText('¥', upx2px(43), upx2px(nextLineX));
  context.setFillStyle('#fa020a');
  context.setFontSize(upx2px(24));
  context.fillText(commission, upx2px(54), upx2px(nextLineX));
  nextLineX += 20;
  context.setFillStyle('#303030');
  context.setFontSize(upx2px(12));
  context.setLineWidth(300);
  context.fillText(desc, upx2px(12), upx2px(nextLineX));
  context.setFillStyle('#5e5e5e');
  context.setFontSize(upx2px(12));
  context.fillText('长按识别·立即带货', winWidth - 118, upx2px(height + height / 4 + 60 + 20));
  context.draw(false, () => {
    createPoster(canvasId, winWidth, winHeight, (res) => {
      callback(res);
    });
  });
};

const showPoster = ref(false);
const posterImg = ref('');
const downloadImage = async (url): Promise<string> => {
  return new Promise<string>((resolve, reject) => {
    Taro.downloadFile({
      url,
      success: (res) => {
        resolve(res.tempFilePath);
      },
      fail: (err) => {
        reject(err);
        Taro.showToast({ title: '图片下载错误', icon: 'none' });
      },
    });
  });
};

// 删除已缓存文件，防止超出存储空间大小限制[同步执行]
const removeSavedFile = async () => {
  // 使用前请先查看支持平台（其他方案：也可以先渲染出图片，当图片加载完成时执行相关方法）
  let count = 0;
  return new Promise((resolve, reject) => {
    Taro.getSavedFileList({
      success(res) {
        // console.log(res)
        count = res.fileList.length;
        if (count > 0) {
          let num = 0;
          const list = res.fileList || [];
          list.forEach((item) => {
            // console.log("执行删除文件。。。")
            Taro.removeSavedFile({
              filePath: item.filePath,
              complete(res) {
                num++;
                if (num === count) {
                  resolve(true);
                }
              },
            });
          });
        } else {
          resolve(true);
        }
      },
      fail(err) {
        reject(err);
        console.log('执行删除文件失败');
      },
    });
  });
};
const makePoster = async () => {
  if (!props.proto) {
    return;
  }
  if (posterImg.value) {
    showPoster.value = true;
    return;
  }
  Taro.showLoading({
    mask: true,
    title: '海报绘制中...',
  }).then();
  const cover = await downloadImage(props.proto.doudian_product.cover);
  const qrcode = await downloadImage('https://doudaixuan.com/assets/xcx.538055c5.jpg');
  console.log(cover, qrcode);
  if (cover === '' || qrcode === '') {
    console.log('图片异常');
    Taro.hideLoading();
    return;
  }
  const { price, title } = props.proto.doudian_product;
  const { commission, commission_ratio } = props.proto;
  const priceStr = (Number(price) / 100).toFixed(2);
  const commissionStr = (Number(commission) / 100).toFixed(2);
  await removeSavedFile();
  if (qrcode) {
    readyProtoPoster(
      cover,
      typeof qrcode === 'string' ? qrcode : '',
      title,
      priceStr,
      commissionStr,
      `${commission_ratio}%`,
      `抖带选 - 达人快速变现/高佣带货平台`,
      (res) => {
        console.log('绘制完毕', res);
        Taro.hideLoading();
        if (res) {
          Taro.previewImage({ urls: [res] }).then((res) => {
            console.log(res);
          });
          posterImg.value = res;
          setTimeout(() => {
            showPoster.value = true;
          }, 60);
        } else {
          Taro.showToast({ title: '生成海报失败,请稍后再试', icon: 'none' });
        }
      },
    );
  } else {
    Taro.hideLoading();
    Taro.showToast({ title: '生成海报图片下载失败,请稍后再试', icon: 'error' }).then();
  }
};
onMounted(() => {
  console.log('海报组件加载');
  makePoster();
});

const clickLeft = () => {
  Taro.navigateBack();
};
</script>

<style lang="less" scoped></style>
